home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / wanderer / game.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-26  |  18.7 KB  |  829 lines

  1. #include "wand_head.h"
  2.  
  3. #define viable(x,y) (((screen[y][x] == ' ') || (screen[y][x] == ':') ||\
  4.     (screen[y][x] == '@') || (screen[y][x] == '+')) && (y >= 0) &&\
  5.     (x >= 0) && (y < NOOFROWS) && (x < ROWLEN))
  6.  
  7. /* typedef struct mon_rec        *//* M002 struct mon_rec moved    */
  8. /*     {                *//* to header file because it     */
  9. /*     int x,y,mx,my;            *//* is needed by save.c    */
  10. /*     char under;            */
  11. /*     struct mon_rec *next,*prev;    */
  12. /*     };                */
  13.  
  14. typedef struct { int d[2] } direction;
  15.  
  16. #ifdef    LINT_ARGS    /* M001 */
  17. direction new_direction(int, int, int, int);
  18. #else
  19. direction new_direction();
  20. #endif
  21.  
  22. extern int jumpscreen();
  23.  
  24. extern int check();
  25.  
  26. extern void showpass();
  27.  
  28. extern void draw_symbol();
  29.  
  30. extern void display();
  31.  
  32. extern int fall();
  33.  
  34. extern void map();
  35.  
  36. extern int debug_disp;
  37. extern int edit_mode;
  38. extern int saved_game;
  39. extern char screen[NOOFROWS][ROWLEN+1];
  40.  
  41. /* Add a spirit to the chain */
  42. /* Maintain a doubly linked list to make reuse possible.
  43.    tail_of_list is *NOT* the last monster allocated, but
  44.    the last monster alloted to a screen.  start_of_list
  45.    is a dummy entry to ease processing. last_of_list
  46.    is the last entry allocated. */
  47. static struct mon_rec start_of_list = {0,0,0,0,0,NULL,NULL};
  48.  
  49. struct mon_rec *tail_of_list;
  50. struct mon_rec *last_of_list;
  51.  
  52. struct mon_rec *make_monster(x,y)
  53. int x,y;
  54. {
  55. char *malloc();
  56. #define MALLOC (struct mon_rec *)malloc(sizeof(struct mon_rec))
  57. struct mon_rec *monster;
  58. if(tail_of_list->next == NULL)
  59.     {
  60.     if((last_of_list = MALLOC) == NULL)
  61.     return NULL;
  62.     tail_of_list->next = last_of_list;
  63.     last_of_list->prev = tail_of_list;
  64.     last_of_list->next = NULL;
  65.     }
  66. monster = tail_of_list = tail_of_list->next;
  67. monster->x = x;
  68. monster->y = y;
  69. monster->mx = 1;      /* always start moving RIGHT. (fix later)  */
  70. monster->my = 0;
  71. monster->under = ' ';
  72. return monster;
  73. }
  74.  
  75. /* 'follow lefthand wall' algorithm for baby monsters */
  76.  
  77. direction new_direction(x,y,bx,by)
  78. int x,y,bx,by;
  79. {
  80. direction out;
  81. if(viable((x+by),(y-bx)))
  82.     {
  83.     out.d[0] = by;
  84.     out.d[1] = -bx;
  85.     return out;
  86.     }
  87. if(viable((x+bx),(y+by)))
  88.     {
  89.     out.d[0] = bx;
  90.     out.d[1] = by;
  91.     return out;
  92.     }
  93. if(viable((x-by),(y+bx)))
  94.     {
  95.     out.d[0] = -by;
  96.     out.d[1] = bx;
  97.     return out;
  98.     }
  99. if(viable((x-bx),(y-by)))
  100.     {
  101.     out.d[0] = -bx;
  102.     out.d[1] = -by;
  103.     return out;
  104.     }
  105. out.d[0] = -bx;
  106. out.d[1] = -by;
  107. return out;
  108. }
  109.  
  110. /* Actual game function - Calls fall() to move
  111.        boulders and arrows recursively */
  112. /* Variable explaination :
  113.     All the var names make sense to ME, but some people think them a bit confusing... :-) So heres an explanation.
  114.    x,y : where you are
  115.    nx,ny : where you're trying to move to
  116.    sx,sy : where the screen window on the playing area is
  117.    mx,my : where the monster is
  118.    tx,ty : teleport arrival
  119.    bx,by : baby monster position
  120.    nbx,nby : where it wants to be
  121.    lx,ly : the place you left when teleporting
  122.    nf : how many diamonds youve got so far
  123.    new_disp : the vector the baby monster is trying
  124. */
  125.  
  126. char *playscreen(num,score,bell,maxmoves,keys)
  127. int  *num, maxmoves,
  128.      *bell,
  129.      *score;
  130. char keys[10];
  131. {
  132. int  x,y,nx,ny,deadyet =0,
  133.      sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1,
  134.      bx, by, nbx, nby,
  135.      newnum,
  136.      max_score = 250,
  137.      diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection;
  138. char (*frow)[ROWLEN+1] = screen,
  139.      ch,
  140.      buffer[25];
  141. static char     howdead[25];    /* M001 can't use auto var for return value */
  142. direction new_disp;
  143. struct mon_rec *monster,*current;
  144.  
  145. tail_of_list = &start_of_list;
  146.  
  147. for(x=0;x<=ROWLEN;x++)
  148.     for(y=0;y<NOOFROWS;y++)
  149.     {
  150.     if((screen[y][x] == '*')||(screen[y][x] == '+'))
  151.         {
  152.         diamonds++;
  153.         max_score += 10;
  154.         if(screen[y][x] == '+')
  155.         max_score += 20;
  156.         }
  157.         if(screen[y][x] == 'A')     /* note teleport arrival point &  */
  158.         {                       /* replace with space */
  159.         tx = x;
  160.         ty = y;
  161.          screen[y][x] = ' ';
  162.         }
  163.         if(screen[y][x] == '@')
  164.         {
  165.         sx = x;
  166.         sy = y;
  167.         }
  168.         if(screen[y][x] == 'M')     /* Put megamonster in */
  169.         {
  170.         mx = x;
  171.         my = y;
  172.         }
  173.     if(screen[y][x] == 'S')     /* link small monster to pointer chain */
  174.         {
  175.         if((monster = make_monster(x,y)) == NULL)
  176.         {
  177.         strcpy(howdead,"running out of memory");
  178.         return howdead;
  179.         }
  180.         if(!viable(x,y-1))     /* make sure its running in the correct */
  181.         {                  /* direction..                          */
  182.         monster->mx = 1;
  183.         monster->my = 0;
  184.         }
  185.         else if(!viable(x+1,y))
  186.         {
  187.         monster->mx = 0;
  188.         monster->my = 1;
  189.         }
  190.         else if(!viable(x,y+1))
  191.         {
  192.         monster->mx = -1;
  193.         monster->my = 0;
  194.         }
  195.         else if(!viable(x-1,y))
  196.         {
  197.         monster->mx = 0;
  198.         monster->my = -1;
  199.         }
  200.         }
  201.         if(screen[y][x] == '-')
  202.             screen[y][x] = ' ';
  203.         };
  204. x=sx;
  205. y=sy;
  206. if((x == -1)&&(y == -1))              /* no start position in screen ? */
  207.     {
  208.     strcpy(howdead,"a screen design error");
  209.     return(howdead);
  210.     }
  211.  
  212. update_game:    /* M002  restored game restarts here    */
  213.  
  214. move(0,48);
  215. (void) addstr("Score\t   Diamonds");
  216. move(1,48);
  217. (void) addstr("\tFound\tTotal");
  218. move(3,48);
  219. (void) sprintf(buffer,"%d\t %d\t %d  ",*score,nf,diamonds);
  220. (void) addstr(buffer);
  221. move(6,48);
  222. (void) sprintf(buffer,"Current screen %d",*num);
  223. (void) addstr(buffer);
  224. if(maxmoves != 0)
  225. (void) sprintf(buffer,"Moves remaining = %d   ",maxmoves);
  226. else
  227. {
  228.     (void) strcpy(buffer,"     Unlimited moves     ");
  229.     maxmoves = -1;
  230. };
  231. move(15,48);
  232. (void) addstr(buffer);
  233. if(mx != -1)                            /* tell player if monster exists */
  234.     draw_symbol(48,10,'M');
  235. else
  236.     draw_symbol(48,10,' ');
  237.  
  238. if(!debug_disp)
  239.     display(sx,sy,frow,*score);
  240. else
  241.     map(frow);
  242.  
  243. /* ACTUAL GAME FUNCTION - Returns method of death in string  */
  244.  
  245. while(deadyet == 0)
  246. {
  247. ch = getch();
  248.  
  249. nx=x;
  250. ny=y;
  251.  
  252. if(ch == keys[3])              /* move about - but thats obvious */
  253.     nx++;
  254. if(ch == keys[2])
  255.     nx--;
  256. if((ch == keys[1]) && (y<(NOOFROWS-1)))
  257.     ny++;
  258. if(ch == keys[0])
  259.         ny--;
  260. if(ch == '1')                  /* Add or get rid of that awful sound */
  261.     {
  262.         move(10,45);
  263.         *bell = 1;
  264.         (void) addstr("Bell ON ");
  265.     move(16,0);
  266.         refresh();
  267.     continue;
  268.     }
  269. if(ch == '0')
  270.     {
  271.         *bell = 0;
  272.         move(10,45);
  273.         (void) addstr("Bell OFF");
  274.     move(16,0);
  275.         refresh();
  276.     continue;
  277.     }
  278. if(ch == '~')                             /* level jump */
  279.     {
  280.     if((newnum = jumpscreen(*num)) == 0)
  281.         {
  282.         strcpy(howdead,"a jump error.");
  283.         return howdead;
  284.         }
  285.     if(newnum != *num)
  286.         {                  /* Sorry Greg, no points for free */
  287.         sprintf(howdead,"~%c",newnum);
  288.         return howdead;
  289.         }
  290.     continue;
  291.     }
  292. if(ch == '!')                      /* look at the map */
  293.     {
  294.     if(debug_disp)
  295.         continue;
  296.     map(frow);
  297.         display(sx,sy,frow,*score);
  298.     continue;
  299.     }
  300. if(ch == 'q')
  301.         {
  302.         strcpy(howdead,"quitting the game");
  303.     return howdead;
  304.     }
  305. if(ch == '?')
  306.     {
  307.     helpme();
  308.     display(sx,sy,frow,*score);
  309.     continue;
  310.     }
  311.  
  312. /* M002  Added save/restore game feature.  Gregory H. Margo    */
  313. if(ch == 'S')           /* save game */
  314.     {
  315.     extern    struct    save_vars    zz;
  316.  
  317.     /* stuff away important local variables to be saved */
  318.     /* so the game state may be acurately restored    */
  319.     zz.z_x        = x;
  320.     zz.z_y        = y;
  321.     zz.z_nx        = nx;
  322.     zz.z_ny        = ny;
  323.     zz.z_sx        = sx;
  324.     zz.z_sy        = sy;
  325.     zz.z_tx        = tx;
  326.     zz.z_ty        = ty;
  327.     zz.z_lx        = lx;
  328.     zz.z_ly        = ly;
  329.     zz.z_mx        = mx;
  330.     zz.z_my        = my;
  331.     zz.z_bx        = bx;
  332.     zz.z_by        = by;
  333.     zz.z_nbx    = nbx;
  334.     zz.z_nby    = nby;
  335.     zz.z_max_score    = max_score;
  336.     zz.z_diamonds    = diamonds;
  337.     zz.z_nf        = nf;
  338.     zz.z_hd        = hd;
  339.     zz.z_vd        = vd;
  340.     zz.z_xdirection    = xdirection;
  341.     zz.z_ydirection    = ydirection;
  342.  
  343.     save_game(*num, score, bell, maxmoves, &start_of_list, tail_of_list);
  344.     /* NOTREACHED */
  345.     }
  346. if(ch == 'R')        /* restore game */
  347.     {
  348.     extern    struct    save_vars    zz;
  349.  
  350.     restore_game(num, score, bell, &maxmoves, &start_of_list, &tail_of_list);
  351.  
  352.     /* recover important local variables */
  353.     x        = zz.z_x;
  354.     y        = zz.z_y;
  355.     nx        = zz.z_nx;
  356.     ny        = zz.z_ny;
  357.     sx        = zz.z_sx;
  358.     sy        = zz.z_sy;
  359.     tx        = zz.z_tx;
  360.     ty        = zz.z_ty;
  361.     lx        = zz.z_lx;
  362.     ly        = zz.z_ly;
  363.     mx        = zz.z_mx;
  364.     my        = zz.z_my;
  365.     bx        = zz.z_bx;
  366.     by        = zz.z_by;
  367.     nbx        = zz.z_nbx;
  368.     nby        = zz.z_nby;
  369.     max_score    = zz.z_max_score;
  370.     diamonds    = zz.z_diamonds;
  371.     nf        = zz.z_nf;
  372.     hd        = zz.z_hd;
  373.     vd        = zz.z_vd;
  374.     xdirection    = zz.z_xdirection;
  375.     ydirection    = zz.z_ydirection;
  376.  
  377.     if (maxmoves == -1)
  378.         maxmoves = 0;    /* to get the "unlimited moves" message */
  379.  
  380.     goto update_game;    /* the dreaded goto    */
  381.     }
  382.  
  383. if(screen[ny][nx] == 'C')
  384.     {
  385.     screen[ny][nx] = ':';
  386.     *score+=4;
  387.     if(maxmoves != -1)
  388.         maxmoves+=250;
  389.     }
  390. switch(screen[ny][nx])
  391.     {
  392.     case '@': break;
  393.     case '*': *score+=9;
  394.     max_score -= 10;
  395.         nf++;
  396.     case ':': *score+=1;
  397.         move(3,48);
  398.         sprintf(buffer,"%d\t %d",*score,nf);
  399.         (void) addstr(buffer);
  400.     case ' ':
  401.     screen[y][x] = ' ';
  402.        screen[ny][nx] = '@';
  403.     if(!debug_disp)
  404.         {
  405.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  406.             draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  407.         }
  408.     else
  409.         {
  410.         move(y+1,x+1);
  411.         addch(' ');
  412.         move(ny+1,nx+1);
  413.         addch('@');
  414.         }
  415.     deadyet += check(&mx,&my,x,y,nx-x,ny-y,sx,sy,howdead);
  416.         move(16,0);
  417.         refresh();
  418.     y = ny;
  419.     x = nx;
  420.         break;
  421.     case 'O':
  422.     if(screen[y][nx*2-x] == 'M')
  423.         {
  424.         screen[y][nx*2-x] = ' ';
  425.         mx = my = -1;
  426.         *score+=100;
  427.             move(3,48);
  428.             sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  429.             (void) addstr(buffer);
  430.         draw_symbol(48,10,' ');
  431.         move(16,0);
  432.             refresh();
  433.         }
  434.     if(screen[y][nx*2-x] == ' ')
  435.         {
  436.         screen[y][nx*2-x] = 'O';
  437.         screen[y][x] = ' ';
  438.             screen[ny][nx] = '@';
  439.         if(!debug_disp)
  440.         {
  441.                 draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  442.                 draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  443.         if(nx*2-x>sx-6&&nx*2-x<sx+6)
  444.                     draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O');
  445.         }
  446.         else
  447.         {
  448.         move(y+1,x+1);
  449.         addch(' ');
  450.         move(ny+1,nx+1);
  451.         addch('@');
  452.         move(y+1,nx*2-x+1);
  453.         addch('O');
  454.         }
  455.             deadyet += fall(&mx,&my,nx*2-x,y+1,sx,sy,howdead);
  456.             deadyet += fall(&mx,&my,x*2-nx,y,sx,sy,howdead);
  457.             deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
  458.             deadyet += fall(&mx,&my,x,y-1,sx,sy,howdead);
  459.             deadyet += fall(&mx,&my,x,y+1,sx,sy,howdead);
  460.             move(16,0);
  461.             refresh();
  462.         y = ny;
  463.         x = nx;
  464.         }
  465.     break;
  466.     case '<':
  467.     case '>':
  468.     if(screen[ny*2-y][x] == 'M')
  469.         {
  470.         screen[ny*2-y][x] = ' ';
  471.         mx = my = -1;
  472.         *score+=100;
  473.             move(3,48);
  474.             sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  475.             (void) addstr(buffer);
  476.         draw_symbol(48,10,' ');
  477.         move(16,0);
  478.             refresh();
  479.         }
  480.     if(screen[ny*2-y][x] == ' ')
  481.         {
  482.         screen[ny*2-y][x] = screen[ny][nx];
  483.         screen[y][x] = ' ';
  484.             screen[ny][nx] = '@';
  485.         if(!debug_disp)
  486.         {
  487.                 draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  488.                 draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  489.         if(ny*2-y>sy-4&&ny*2-y<sy+4)
  490.                     draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]);
  491.         }
  492.         else
  493.         {
  494.         move(y+1,x+1);
  495.         addch(' ');
  496.         move(ny+1,nx+1);
  497.         addch('@');
  498.         move(ny*2-y+1,x+1);
  499.         addch(screen[ny*2-y][x]);
  500.         }
  501.             deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
  502.             deadyet += fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,howdead);
  503.             deadyet += fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,howdead);
  504.             deadyet += fall(&mx,&my,x-1,ny*2-y,sx,sy,howdead);
  505.             deadyet += fall(&mx,&my,x+1,ny*2-y,sx,sy,howdead);
  506.             move(16,0);
  507.             refresh();
  508.         y = ny;
  509.         x = nx;
  510.         }
  511.     break;
  512.     case '!':
  513.         strcpy(howdead,"an exploding landmine");
  514.     deadyet = 1;
  515.     if(!debug_disp)
  516.         {
  517.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  518.             draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
  519.         }
  520.     else
  521.         {
  522.         move(y+1,x+1);
  523.         addch(' ');
  524.         move(ny+1,nx+1);
  525.         addch('@');
  526.         }
  527.         move(16,0);
  528.     refresh();
  529.         break;
  530.     case 'X':
  531.     if(nf == diamonds)
  532.         {
  533.         *score+=250;
  534.         showpass(*num);
  535.         return NULL;
  536.         }
  537.     break;
  538.     case 'T':
  539.     if(tx > -1)
  540.         {
  541.         screen[ny][nx] = ' ';
  542.         screen[y][x] = ' ';
  543.         lx = x;
  544.         ly = y;
  545.         y = ty;
  546.         x = tx;
  547.         screen[y][x] = '@';
  548.         sx = x;
  549.         sy = y;
  550.         *score += 20;
  551.             move(3,48);
  552.             sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  553.             (void) addstr(buffer);
  554.         if(!debug_disp)
  555.             display(sx,sy,frow,*score);
  556.         else
  557.         map(frow);
  558.         deadyet = fall(&mx,&my,nx,ny,sx,sy,howdead);
  559.         if(deadyet == 0)
  560.         deadyet = fall(&mx,&my,lx,ly,sx,sy,howdead);
  561.         if(deadyet == 0)
  562.         deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,howdead);
  563.         if(deadyet == 0)
  564.         deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,howdead);
  565.         if(deadyet == 0)
  566.         deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,howdead);
  567.         if(deadyet == 0)
  568.         deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,howdead);
  569.         move(16,0);
  570.         refresh();
  571.         }
  572.     else
  573.         {
  574.         screen[ny][nx] = ' ';
  575.         printf("Teleport out of order");
  576.         }
  577.     break;
  578.     case 'M':
  579.     strcpy(howdead,"a hungry monster");
  580.     deadyet = 1;
  581.     if(!debug_disp)
  582.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  583.     else
  584.         {
  585.         move(y+1,x+1);
  586.         addch(' ');
  587.         }
  588.         move(16,0);
  589.     refresh();
  590.         break;
  591.     case 'S':
  592.     strcpy(howdead,"walking into a monster");
  593.     deadyet = 1;
  594.     if(!debug_disp)
  595.             draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
  596.     else
  597.         {
  598.         move(y+1,x+1);
  599.         addch(' ');
  600.         }
  601.         move(16,0);
  602.     refresh();
  603.         break;
  604.     default:
  605.         break;
  606.     }
  607. if((y == ny) && (x == nx) && (maxmoves>0))
  608.     {
  609.     (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves);
  610.     move(15,48);
  611.     (void) addstr(buffer);
  612.     }
  613. if(maxmoves == 0)
  614.     {
  615.     strcpy(howdead,"running out of time");
  616.     return(howdead);
  617.     }
  618. if(!debug_disp)
  619.     {
  620.     if ((x<(sx-3))&& (deadyet ==0))         /* screen scrolling if necessary */
  621.         {
  622.         sx-=6;
  623.         if(sx < 4)
  624.         sx = 4;
  625.         display(sx,sy,frow,*score);
  626.         }
  627.     if ((y<(sy-2))&& (deadyet == 0))
  628.         {
  629.         sy-=5;
  630.         if(sy < 2)
  631.         sy = 2;
  632.         display(sx,sy,frow,*score);
  633.         }
  634.     if ((x>(sx+3)) && (deadyet == 0))
  635.         {
  636.         sx+=6;
  637.         if(sx>(ROWLEN -5))
  638.         sx = ROWLEN -5;
  639.         display(sx,sy,frow,*score);
  640.         }
  641.     if ((y>(sy+2))&& (deadyet ==0))
  642.         {
  643.         sy+=5;
  644.         if(sy > (NOOFROWS-3))
  645.         sy = NOOFROWS -3;
  646.         display(sx,sy,frow,*score);
  647.         }
  648.     }
  649.  
  650.     /* MONSTER SECTION  */
  651.  
  652. /* big monster first */
  653. if(mx == -2)                              /* has the monster been killed ? */
  654.     {
  655.     *score+=100;
  656.     mx = my = -1;
  657.     move(3,48);
  658.     sprintf(buffer,"%d\t %d\t",*score,nf);
  659.     (void) addstr(buffer);
  660.     draw_symbol(48,10,' ');
  661.     move(16,0);
  662.     refresh();
  663.     }                                     /* if monster still alive */
  664. if(mx != -1)                              /* then move that monster ! */
  665.     {
  666.     screen[my][mx] = ' ';
  667.     if(mx>x)
  668.         xdirection = -1;
  669.     else
  670.         xdirection = 1;
  671.     if(!debug_disp)
  672.     {
  673.         if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
  674.             draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' ');
  675.     }
  676.     else
  677.     {
  678.     move(my+1,mx+1);
  679.     addch(' ');
  680.     }
  681.     if((hd = (mx-x))<0)
  682.     hd = -hd;
  683.     if((vd = (my-y))<0)
  684.     vd = -vd;
  685.     if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')))
  686.     mx+=xdirection;
  687.     else
  688.         {
  689.         if(my>y)
  690.             ydirection = -1;
  691.     else
  692.             ydirection = 1;
  693.         if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@'))
  694.         my+=ydirection;
  695.     else
  696.             if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))
  697.     mx+=xdirection;
  698.     }
  699.     if(!debug_disp)
  700.     {
  701.         if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
  702.             draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M');
  703.     }
  704.     else
  705.     {
  706.     move(my+1,mx+1);
  707.     addch('M');
  708.     }
  709.     if(screen[my][mx] == '@')                     /* ha! gottim! */
  710.     {
  711.     strcpy(howdead,"a hungry monster");
  712.         move(16,0);
  713.     refresh();
  714.         return(howdead);
  715.     }
  716.     screen[my][mx] = 'M';
  717.     move(16,0);
  718.     refresh();
  719.     }
  720.  
  721. current = &start_of_list;
  722. while((current != tail_of_list)&&(!deadyet))
  723.     /* deal with those little monsters */
  724.     {
  725.     monster = current->next;
  726.     new_disp = new_direction( monster->x, monster->y, monster->mx, monster->my );
  727.     if(monster->under!='S')
  728.     {
  729.         screen[monster->y][monster->x] = monster->under;
  730.         if(!debug_disp)
  731.         {
  732.             if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
  733.                 draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under);
  734.         }
  735.         else
  736.         {
  737.             move(monster->y+1,monster->x+1);
  738.             addch(monster->under);
  739.         }
  740.         if(monster->under == ' ')
  741.          deadyet+=check(&mx,&my,monster->x,monster->y,new_disp.d[0],new_disp.d[1],sx,sy,howdead);
  742.     }
  743.     else
  744.     monster->under=' ';
  745.     monster->mx = new_disp.d[0];
  746.     monster->my = new_disp.d[1];
  747.     monster->x += monster->mx;
  748.     monster->y += monster->my;
  749.     monster->under = screen[monster->y][monster->x];
  750.     screen[monster->y][monster->x] = 'S';        /* move into new space */
  751.     if(!debug_disp)
  752.     {
  753.         if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
  754.             draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S');
  755.     }
  756.     else
  757.     {
  758.     move(monster->y+1,monster->x+1);
  759.     addch('S');
  760.     }
  761.     if(monster->under == '@')                     /* monster hit you? */
  762.         {
  763.     strcpy(howdead,"the little monsters");
  764.     move(16,0);
  765.     refresh();
  766.         return(howdead);
  767.         }
  768.     if(monster->under == '+')                    /* monster hit cage? */
  769.         {
  770.     *score +=20;
  771.     max_score -= 20;
  772.         move(3,48);
  773.         sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
  774.         (void) addstr(buffer);
  775.         /* remove from chain, and insert at the end (at last_of_list) */
  776.     if(monster == tail_of_list)
  777.         tail_of_list = tail_of_list->prev;
  778.     else
  779.         {
  780.           current->next = monster-> next;
  781.         current->next->prev = current;
  782.         monster->next = NULL;
  783.         monster->prev = last_of_list;
  784.         last_of_list->next = monster;
  785.         last_of_list = monster;
  786.         }
  787.     screen[monster->y][monster->x] = '*';
  788.     if(!debug_disp)
  789.         {
  790.             if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
  791.                     draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*');
  792.         }
  793.     else
  794.         {
  795.         move(monster->y+1,monster->x+1);
  796.         addch('*');
  797.         }
  798.         }
  799.     else
  800.     current = monster;
  801.     move(16,0);
  802.     refresh();
  803.     }
  804.  
  805. if((edit_mode)&&(deadyet)) {         /* stop death if testing */
  806.     if(!debug_disp)
  807.     move(18,0);
  808.     else
  809.     move(20,0);
  810.     addstr("You were killed by ");
  811.     addstr(howdead);
  812.     addstr("\nPress 'c' to continue.");
  813.     refresh();
  814.     ch=getch();
  815.     if(ch == 'c')
  816.     deadyet = 0;
  817.     if(!debug_disp)
  818.     move(18,0);
  819.      else
  820.     move(20,0);
  821.     addstr("                                                              ");
  822.     addstr("\n                      ");
  823.     refresh();
  824.     }
  825.  
  826. }
  827. return(howdead);
  828. }
  829.